package com.quick.android.view.ptr;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.quick.android.R;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class PtrListView extends ListView implements OnScrollListener {
	// 释放刷新
	private final static int RELEASE_To_REFRESH = 0;
	// 下拉刷新
	private final static int PULL_To_REFRESH = 1;
	// 正在刷新
	private final static int REFRESHING = 2;
	// 刷新完成
	private final static int DONE = 3;
	private final static int LOADING = 4;

	private final static int RATIO = 3;
	private LayoutInflater inflater;
	private LinearLayout headView;
	private TextView tipsTextview;
	private TextView lastUpdatedTextView;
	private ImageView arrowImageView;
	private ProgressBar mProgressBar;

	private RotateAnimation animation;
	private RotateAnimation reverseAnimation;
	private boolean isRecored;
	// private int headContentWidth;
	private int headContentHeight;
	private int startY;
	private int firstItemIndex;
	public int state;
	private boolean isBack;
	private OnRefreshListener refreshListener;
	private boolean isRefreshable;

	private LinearLayout footView;
	private OnLoadMoreListener loadMoreListener;
	public boolean isLoadMoreable;
	public boolean isMore = false;
	private boolean isLoadingmore = false;

	public boolean isFling;

	int i = 1;

	public PtrListView(Context context) {
		super(context);
		init(context);
	}

	public PtrListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public void addVisibleHeadView(View view) {
		headView.addView(view);

	}

	private void init(Context context) {
		inflater = LayoutInflater.from(context);
		headView = (LinearLayout) inflater.inflate(
				R.layout.listview_refresh_head_white, null);
		arrowImageView = (ImageView) headView
				.findViewById(R.id.head_arrowImageView);
		arrowImageView.setMinimumWidth(70);
		arrowImageView.setMinimumHeight(50);
		tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);
		lastUpdatedTextView = (TextView) headView
				.findViewById(R.id.head_lastUpdatedTextView);
		mProgressBar = (ProgressBar) headView
				.findViewById(R.id.head_progressBar);
		mProgressBar.setVisibility(View.INVISIBLE);
		measureView(headView);
		headContentHeight = headView.getMeasuredHeight();
		// headContentWidth = headView.getMeasuredWidth();
		headView.setPadding(0, -1 * headContentHeight, 0, 0);
		headView.invalidate();
		addHeaderView(headView, null, false);

		footView = new LinearLayout(context);
		footView.setVisibility(View.INVISIBLE);
		footView.setOrientation(LinearLayout.HORIZONTAL);
		footView.setGravity(Gravity.CENTER);
		android.widget.LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
				LinearLayout.LayoutParams.WRAP_CONTENT,
				LinearLayout.LayoutParams.WRAP_CONTENT);
		LinearLayout loading = new LinearLayout(context);
		ProgressBar progressBar = new ProgressBar(context);
		progressBar.setPadding(0, 0, 15, 0);
		loading.addView(progressBar, layoutParams);
		footView.addView(loading, layoutParams);
		footView.invalidate();
		// addFooterView(footView, null, false);
		setFooterDividersEnabled(false);
		footView.setVisibility(View.INVISIBLE);

		setOnScrollListener(this);

		animation = new RotateAnimation(180, 0,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		// animation = new RotateAnimation(0, 0,
		// RotateAnimation.RELATIVE_TO_SELF,
		// 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		animation.setInterpolator(new LinearInterpolator());
		animation.setDuration(250);
		animation.setFillAfter(true);

		reverseAnimation = new RotateAnimation(-180, 0,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		// reverseAnimation = new RotateAnimation(0, 0,
		// RotateAnimation.RELATIVE_TO_SELF, 0.5f,
		// RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		reverseAnimation.setInterpolator(new LinearInterpolator());
		reverseAnimation.setDuration(200);
		reverseAnimation.setFillAfter(true);

		state = DONE;
		isRefreshable = false;
	}

	public void onScroll(AbsListView view, int firstVisiableItem,
			int visibleItemCount, int totalItemCount) {
		firstItemIndex = firstVisiableItem;
		if (firstVisiableItem + visibleItemCount >= totalItemCount - 1
				&& !isLoadingmore && isMore && isLoadMoreable) {
			onLoadMore();
		}
	}

	public void onScrollStateChanged(AbsListView view, int scrollState) {
		switch (scrollState) {
		case OnScrollListener.SCROLL_STATE_FLING:
			// fling
		case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
			// prepare
			isFling = true;
			break;
		case OnScrollListener.SCROLL_STATE_IDLE:
			// stop
			isFling = false;
			break;
		default:
			break;
		}
	}

	public boolean onTouchEvent(MotionEvent event) {
		if (isRefreshable) {
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				if (firstItemIndex == 0 && !isRecored) {
					isRecored = true;
					startY = (int) event.getY();
				}
				break;
			case MotionEvent.ACTION_UP:
				if (state != REFRESHING && state != LOADING) {
					if (state == DONE) {
					}
					if (state == PULL_To_REFRESH) {
						state = DONE;
						changeHeaderViewByState();
					}
					if (state == RELEASE_To_REFRESH) {
						state = REFRESHING;
						changeHeaderViewByState();
						onRefresh();
					}
				}
				isRecored = false;
				isBack = false;
				break;
			case MotionEvent.ACTION_MOVE:
				int tempY = (int) event.getY();
				if (!isRecored && firstItemIndex == 0) {
					isRecored = true;
					startY = tempY;
				}
				if (state != REFRESHING && isRecored && state != LOADING) {
					if (state == RELEASE_To_REFRESH) {
						setSelection(0);
						if (((tempY - startY) / RATIO < headContentHeight)
								&& (tempY - startY) > 0) {
							state = PULL_To_REFRESH;
							changeHeaderViewByState();
						} else if (tempY - startY <= 0) {
							state = DONE;
							changeHeaderViewByState();
						}
					}
					if (state == PULL_To_REFRESH) {
						setSelection(0);
						if ((tempY - startY) / RATIO >= headContentHeight) {
							state = RELEASE_To_REFRESH;
							isBack = true;
							changeHeaderViewByState();
						} else if (tempY - startY <= 0) {
							state = DONE;
							changeHeaderViewByState();
						}
					}
					if (state == DONE) {
						if (tempY - startY > 0) {
							state = PULL_To_REFRESH;
							changeHeaderViewByState();
						}
					}
					if (state == PULL_To_REFRESH) {
						headView.setPadding(0, -1 * headContentHeight
								+ (tempY - startY) / RATIO, 0, 0);
					}
					if (state == RELEASE_To_REFRESH) {
						headView.setPadding(0, (tempY - startY) / RATIO
								- headContentHeight, 0, 0);
					}
				}
				break;
			}
		}
		return super.onTouchEvent(event);
	}

	private void changeHeaderViewByState() {
		switch (state) {
		case RELEASE_To_REFRESH:
			arrowImageView.setVisibility(View.VISIBLE);
			tipsTextview.setVisibility(View.VISIBLE);
			lastUpdatedTextView.setVisibility(View.VISIBLE);
			mProgressBar.setVisibility(View.INVISIBLE);
			arrowImageView.clearAnimation();
			arrowImageView.setImageResource(R.drawable.z_arrow_up);
			arrowImageView.startAnimation(animation);
			mProgressBar.setVisibility(View.INVISIBLE);
			tipsTextview.setText("释放后 刷新");
			break;
		case PULL_To_REFRESH:
			tipsTextview.setVisibility(View.VISIBLE);
			lastUpdatedTextView.setVisibility(View.VISIBLE);
			arrowImageView.clearAnimation();
			arrowImageView.setVisibility(View.VISIBLE);
			mProgressBar.setVisibility(View.INVISIBLE);
			arrowImageView.setImageResource(R.drawable.z_arrow_down);
			if (isBack) {
				isBack = false;
				arrowImageView.clearAnimation();
				arrowImageView.startAnimation(reverseAnimation);
				// tipsTextview.setText("取消刷新");
				tipsTextview.setText("下拉可刷新");
			} else {
				tipsTextview.setText("下拉可刷新");
			}
			break;
		case REFRESHING:
			headView.setPadding(0, 0, 0, 0);
			arrowImageView.clearAnimation();
			arrowImageView.setVisibility(View.INVISIBLE);
			tipsTextview.setText("正在刷新 ...");
			lastUpdatedTextView.setVisibility(View.VISIBLE);
			mProgressBar.setVisibility(View.VISIBLE);
			break;
		case DONE:
			headView.setPadding(0, -1 * headContentHeight, 0, 0);
			arrowImageView.clearAnimation();
			arrowImageView.setImageResource(R.drawable.z_arrow_down);
			arrowImageView.setVisibility(View.VISIBLE);
			tipsTextview.setText("刷新完成");
			lastUpdatedTextView.setVisibility(View.VISIBLE);
			mProgressBar.setVisibility(View.INVISIBLE);
			break;
		}
	}

	public void setonRefreshListener(OnRefreshListener refreshListener) {
		this.refreshListener = refreshListener;
		isRefreshable = true;
	}

	public interface OnRefreshListener {
		public void onRefresh();
	}

	public void onRefreshComplete() {
		state = DONE;
		SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
		Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
		lastUpdatedTextView.setText("上次刷新: " + formatter.format(curDate));
		changeHeaderViewByState();
		if (loadMoreListener != null) {
			isLoadMoreable = true;
			removeFooterView(footView);
			if (isMore)
				addFooterView(footView, null, false);
		}
	}

	public void onRefresh() {
		isLoadMoreable = false;
		isLoadingmore = false;
		removeFooterView(footView);
		if (refreshListener != null) {
			refreshListener.onRefresh();
		}
	}

	public void setonLoadMoreListener(OnLoadMoreListener loadMoreListener) {
		this.loadMoreListener = loadMoreListener;
	}

	public interface OnLoadMoreListener {
		public void onLoadMore();
	}

	public void onLoadMoreComplete() {
		isLoadingmore = false;
		footView.setVisibility(View.INVISIBLE);
		if (!isMore)
			removeFooterView(footView);
	}

	public void onLoadMore() {
		footView.setVisibility(View.VISIBLE);
		isLoadingmore = true;
		if (loadMoreListener != null) {
			loadMoreListener.onLoadMore();
		}
	}

	private void measureView(View child) {
		ViewGroup.LayoutParams p = child.getLayoutParams();
		if (p == null) {
			p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
		}
		int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
		int lpHeight = p.height;
		int childHeightSpec;
		if (lpHeight > 0) {
			childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
					MeasureSpec.EXACTLY);
		} else {
			childHeightSpec = MeasureSpec.makeMeasureSpec(0,
					MeasureSpec.UNSPECIFIED);
		}
		child.measure(childWidthSpec, childHeightSpec);
	}

	public void setAdapter(BaseAdapter adapter) {
		super.setAdapter(adapter);
	}

	@Override
	protected void dispatchDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		try {
			super.dispatchDraw(canvas);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}